package com.ruoyi.trainScript.service.impl;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.util.Date;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.trainScript.service.IScriptTrainService;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.trainScript.mapper.BoleScrpitTrainRecordMapper;
import com.ruoyi.trainScript.domain.BoleScrpitTrainRecord;

/**
 * 训练脚本调用Service业务层处理
 * 
 * @author assistant
 * @date 2024-07-11
 */
@Service
public class ScriptTrainServiceImpl implements IScriptTrainService {

    @Autowired
    private BoleScrpitTrainRecordMapper boleScrpitTrainRecordMapper;

    /**
     * 调用训练脚本
     * 
     * @param dataPath 数据文件路径
     * @return 训练结果
     */
    @Override
    public String callTrainScript(String dataPath) {
        if (StringUtils.isEmpty(dataPath)) {
            return "参数错误：数据文件路径不能为空";
        }

        StringBuilder result = new StringBuilder();
        ProcessBuilder processBuilder = new ProcessBuilder();
        
        // 创建训练记录
        BoleScrpitTrainRecord trainRecord = new BoleScrpitTrainRecord();
        trainRecord.setTrainJob("岗位预测模型训练");
        trainRecord.setTrainJobCode("JOB_PREDICT");
        trainRecord.setDataPath(dataPath);
        
        // 获取数据文件大小
        java.io.File dataFile = new java.io.File(
            "e:\\xit.edu.cn\\bole\\RuoYi\\RuoYi-Vue-master\\bole-resume\\recommendation-algorithm\\" + dataPath
        );
        if (dataFile.exists()) {
            trainRecord.setDataSize(dataFile.length());
        }
        
        trainRecord.setModelVersion("1.0.0");
        trainRecord.setTrainStatus(0L); // 0：未开始
        trainRecord.setTrainStartTime(new Date());
        trainRecord.setCreateTime(DateUtils.getNowDate());
        
        // 插入训练记录
        int insertResult = boleScrpitTrainRecordMapper.insertBoleScrpitTrainRecord(trainRecord);
        if (insertResult > 0) {
            result.append("训练记录创建成功，ID: " + trainRecord.getId() + "\n");
        } else {
            result.append("训练记录创建失败\n");
        }

        // 更新训练状态为训练中
        trainRecord.setTrainStatus(1L); // 1：训练中
        boleScrpitTrainRecordMapper.updateBoleScrpitTrainRecord(trainRecord);
        
        // 设置命令和参数
        // 命令格式: python scripts\retrain_with_new_data.py recommendation-algorithm\student_job_data.csv
        processBuilder.command(
            "python", 
            "scripts\\retrain_with_new_data.py", 
            dataPath
        );

        // 设置工作目录（脚本所在目录）
        processBuilder.directory(
            new java.io.File("e:\\xit.edu.cn\\bole\\RuoYi\\RuoYi-Vue-master\\bole-resume\\recommendation-algorithm")
        );

        try {
            // 启动进程
            Process process = processBuilder.start();

            // 读取输出
            BufferedReader reader = new BufferedReader(
                new InputStreamReader(process.getInputStream(), "GBK")
            );

            String line;
            while ((line = reader.readLine()) != null) {
                result.append(line).append("\n");
            }

            // 读取错误输出
            BufferedReader errorReader = new BufferedReader(
                new InputStreamReader(process.getErrorStream(), "GBK")
            );

            String errorLine;
            while ((errorLine = errorReader.readLine()) != null) {
                result.append("错误: " + errorLine).append("\n");
            }

            // 等待进程完成
            int exitCode = process.waitFor();
            
            // 更新训练记录
            trainRecord.setTrainEndTime(new Date());
            
            if (exitCode == 0) {
                result.append("\n训练脚本执行成功, 退出码: " + exitCode);
                trainRecord.setTrainStatus(2L); // 2：成功
                // 假设准确率等指标可以从结果中解析，这里暂时设置为示例值
               // trainRecord.setAccuracy(new BigDecimal(85.5));
               // trainRecord.setPrecision(new BigDecimal(82.3));
               // trainRecord.setRecall(new BigDecimal(87.1));
               // trainRecord.setF1Score(new BigDecimal(84.6));
                trainRecord.setTrainParams("{\"epoch\":50,\"batch_size\":32}");
                trainRecord.setErrorMsg(result.toString());
            } else {
                result.append("\n训练脚本执行失败, 退出码: " + exitCode);
                trainRecord.setTrainStatus(3L); // 3：失败
                trainRecord.setErrorMsg("训练脚本执行失败，退出码: " + exitCode);
            }
            
            trainRecord.setUpdateTime(DateUtils.getNowDate());
            boleScrpitTrainRecordMapper.updateBoleScrpitTrainRecord(trainRecord);

        } catch (IOException | InterruptedException e) {
            result.append("执行脚本时发生错误: " + e.getMessage());
            // 更新训练记录为失败
            if (trainRecord.getId() != null) {
                trainRecord.setTrainStatus(3L); // 3：失败
                trainRecord.setErrorMsg("执行脚本时发生错误: " + e.getMessage());
                trainRecord.setUpdateTime(DateUtils.getNowDate());
                boleScrpitTrainRecordMapper.updateBoleScrpitTrainRecord(trainRecord);
            }
        }

        return result.toString();
    }
}